<?php
	
	class FileHandler {
		
    const CREATED = 1;
    const NOT_CREATED = 2;
    const EXISTS = 3;
    const SKIP = 4;
    static $forbidden_list_elements = array('.', '..', '.svn');
		
		
    
    ### READ METHODS
    
		# List folder method
		public function list_folder_items($path, $return_type = 'elements') { //, $new_forbidden = false) {

      //$pattern = preg_quote(S);
      //$pattern = str_replace('/', '\\/', $pattern);
      $path .= '/';
      $path = str_replace('\\/', S, $path);
      $path = str_replace('//', S, $path);
      
      # Checking if $path is directory...
      if (!is_dir($path)) {
        Akrudo::raise_err("Directory not found: {$path}");
      }
      
			$forbidden = self::$forbidden_list_elements;
			//$forbidden = array_merge($forbidden, explode('|', $new_forbidden));
			
      
      
      $dir = dir($path);
      $elements = array();
      $directories = array();
      $files = array();
			while (false !== ($filename = $dir->read())) {
				if (!in_array($filename, $forbidden)) {
          switch (is_dir($path . $filename)) {
            case true:
                $element = new Dir($path . $filename);
                $directories[] = $element;
              break;
              
            case false:
                $element = new File($path . $filename);
                $files[strval($element->mtime)][] = $element;
              break;
          }
          $elements[] = $element;
				}
			}
      $dir->close();
      
      
      // This code really sucks....
      ksort($files);
      $new_files = array();
			foreach ($files as $file_set) {
			  foreach ($file_set as $file) {
			    $new_files[] = $file;
			  }
			}
			
			
			
      $filehandler = new FileHandler();
      $filehandler->elements = $elements;
      $filehandler->directories = $directories;
      $filehandler->files = $new_files;
			return $filehandler->$return_type;
		}
		
		# List folder's directories; uses List folder method
		public function list_folder_directories($path) {
			return self::list_folder_items($path, 'directories');
    }
		
		# List folder's files; uses List folder method
		public function list_folder_files($path, $type = false) {
			return self::list_folder_items($path, 'files');
		}
		
    
    
    
    
    
    
    
    
    
    
    
    
    
    ### OPERATION METHODS
		
		# Removes directory
		public function remove_directory($path) {
			if (is_dir($path)) {
				if (rmdir($path)) {
					return 1;
				} else {
					return 2;
				}
			} else {
				return 3;
			}
		}
		
		# Creates directory
		public function create_directory($path, $privileges = 0777) {
			if (!is_dir(dirname($path))) {
        $subpath = dirname($path);
        //pc($subpath);
        self::create_directory($subpath, $privileges);
			}
			if (!is_dir($path)) {
				if (mkdir($path, $privileges)) {
					return self::CREATED;
				} else {
					return self::NOT_CREATED;
				}
			} else {
				return self::EXISTS;
			}
		}
		
		# Removes specified file
		public function RemoveFile($path) {
			if (file_exists($path)) {
				if (unlink($path)) {
					return true;
				}
			}
			return false;
		}
		
		# Creates file with specified text inside
		public function CreateFile($path, $text = '') {
			if ($fhandle = fopen($path, 'x')) {
				fputs($fhandle, $text);
				fclose($fhandle);
				return $fhandle;
			} else {
				return false;
			}
		}
		
		
		# Adds text to specified file
		public function WriteToFile($path, $text) {
			if ($fhandle = fopen($path, 'a')) {
				fputs($fhandle, $text);
				fclose($fhandle);
				return $fhandle;
			} else {
				return false;
			}
		}
		
		
		# Reads specified file
		public function ReadFile($path, $number_of_last_lines = false, $flat = false) {
			
			$fileo = file($path);
			$am = count($fileo);
			$out = '';  
			if ($number_of_last_lines > 0) {
				for ($i = $number_of_last_lines; $i > 0; $i--) {
					$out .= $fileo[$am-$i];
				}
			} else {
				for ($i = $am + $number_of_last_lines; $i > 0; $i--) {
					if ($flat) {
						$out .= trim($fileo[$am-$i]);
					} else {
						$out .= $fileo[$am-$i];
					}
				}
			}
			return $out;
		}
		
		function ReadAndClearFile($path) {
			
			if (file_exists($path)) {
				if ($fileo = fopen($path, "r+")) {
					if (flock($fileo, LOCK_EX)) {
						$out = file_get_contents ($path);
						ftruncate($fileo, 0);
						flock($fileo, LOCK_UN);
					}
					fclose($fileo);
				}
			}
			return $out;
		}
		
		# Counts lines of text in specified file
		public function CountLines($path) {
			$fileo = file($path);
			return count($fileo);
		}
		
		
		
		# Truncates file
		public function ClearFile($path) {
			$fhandle = fopen($path, 'w');
			fclose($fhandle);
		}
		
		
		
		
		# Force to create file with specified text
		public function ForcedCreateFile($path, $text = '') {
			if (file_exists($path)) {
				self::ClearFile($path);
				if (self::WriteToFile($path, $text)) {
					return self::CREATED;
				}
			} else {
				if (self::CreateFile($path, $text)) {
					return self::CREATED;
				}
			}
			return self::NOT_CREATED;
		}
		
		
		
		
		
		### Image connected methods
		
		public function Upload($path_to, $new_name, $input_name, $forced_extension = false) {
			if (!isset($this)) {
			}
			if (array_key_exists($input_name,$_FILES)) {
				if (array_key_exists('name',$_FILES[$input_name])) {
					if (isset($this)) {
						$old_filename = $_FILES[$input_name]['name'];
					} else {
						$old_filename = $_FILES[$input_name]['name'];
					}
					
					// Forced extension
					$extension = $forced_extension;
					
					// Exploding filename
					$exp_filename = explode('.',$_FILES[$input_name]['name']);
					
					// If not forced => Get old file extension
					if (!$extension) {
						$extension = "." . $exp_filename[(count($exp_filename)-1)];
					}
					
					// If newname not included => Create old filename
					if ($new_name == false) {
						array_pop($exp_filename);
						$new_name = implode('.', $exp_filename);
					}
					
					if (file_exists($path_to . $new_name . $extension))
						unlink($path_to . $new_name . $extension);
					if (move_uploaded_file($_FILES[$input_name]['tmp_name'], $path_to . $new_name . $extension)) {  
            Akrudo::raise_info("      [file   UPLOAD COMPLETE: '{$old_filename}' => '{$path_to}{$new_name}{$extension}'");
					  //pc ($_FILES[$input_name]['tmp_name'], $path_to . $new_name . $extension);
						if (chmod($path_to . $new_name . $extension, 0604)) {
							$file = new File($path_to . $new_name . $extension);
              $file->old_basename = $old_filename;
              return $file;
						}
					}
				}
        return false;
			}
      Akrudo::raise_err("      [file   UPLOAD ERROR! '{$old_filename}' => '{$path_to}{$new_name}{$extension}'!");
			return false;
		}
		
    public function if_exists($path){
      if (file_exists($path) || is_dir($path)) {
        return true;
      } else {
        return false;
      }
    }
    
    
		public function delete($path) {
			if (self::if_exists($path)) {
				if (unlink($path)) {
          Akrudo::raise_info("      [file   FILE DELETED: '{$path}'");
					return true;
				} else {
          Akrudo::raise_err("Can't delete '{$path}'. Unknown reason.");
        }
      } else {
        Akrudo::raise_err("Can't delete '{$path}'. File doesn't exists.");
      }
      return false;
		}
		
		public function GetNewName() {
			return $this->new_filename;
		}
		
		public function GetOldName() {
			return $this->old_filename;
		}
		
		public function Copy ($file_from, $file_to) {
			if (file_exists($file_from)) {
				if (copy($file_from, $file_to)) {
					return 'file_copied';
				} else {
					return 'file_not_copied';
				}
			} else {
				return 'file_does_not_exist';
			}
		}
    
	}
  
	
?>